package com.xg.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xg.sys.entity.SysRole;
import com.xg.sys.entity.SysRoleMenu;
import com.xg.sys.entity.SysUser;
import com.xg.sys.entity.SysUserRole;
import com.xg.sys.mapper.SysRoleMapper;
import com.xg.sys.service.SysRoleMenuService;
import com.xg.sys.service.SysRoleService;
import com.xg.sys.service.SysUserRoleService;
import com.xg.sys.service.SysUserService;
import com.xg.frame.constant.Constant;
import com.xg.frame.exception.SqException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author ChenLiang
 * @since 2019-04-17
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysRoleMenuService sysRoleMenuService;
    @Resource
    private SysUserRoleService sysUserRoleService;

    @Override
    public void getPageList(Page<SysRole> page, SysRole data) {

    	QueryWrapper<SysRole> queryWrapper = new QueryWrapper<SysRole>();

        if (!StringUtils.isEmpty(data.getRoleName())){
        	queryWrapper.like("role_name", data.getRoleName());
        }

        queryWrapper.orderByAsc("create_time");
        baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRole(SysRole sysRole) {
        SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        Long userId = sysUser.getId();
        sysRole.setCreateUserId(userId);
        sysRole.setCreateTime(new Date());
        baseMapper.insert(sysRole);
        //保存角色和菜单的关系
        sysRoleMenuService.saveRoleOrUpdateRole(sysRole.getId(),sysRole.getMenuIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {

        //删除角色
       this.removeByIds(Arrays.asList(ids));
        //删除角色与菜单之间的关系

        sysRoleMenuService.deleteBatch(ids);

        //删除角色与用户之间的关联
        sysUserRoleService.deleteBatch(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRole(SysRole sysRole) {
    	 baseMapper.updateById(sysRole);
         //保存角色和菜单的关系
         sysRoleMenuService.saveRoleOrUpdateRole(sysRole.getId(),sysRole.getMenuIdList());
    }

    @Override
    public List<Long> selectRoleIdList(Long createUserId) {
        return baseMapper.selectRoleIdList(createUserId);
    }

    /**
     * 查看是否超越权限
     */
    private void checkPerms(SysRole sysRole) {
        if (Constant.SUPPER_ADMIN.equals(sysRole.getCreateUserId())) {
            return;
        }
        /**
         * 查询用户所拥有的菜单列表
         */
        List<Long> menuIdList = sysUserService.selectAllMenuIds(sysRole.getCreateUserId());
        if (!menuIdList.containsAll(sysRole.getMenuIdList())){
            throw new SqException(20001,"新增角色的权限,超过了您的权限");
        }
    }

    @Override
    public List<SysRole> getByRoleName(String roleName) {
        return this.list(
                new LambdaQueryWrapper<SysRole>()
                        .eq(StringUtils.isNotBlank(roleName), SysRole::getRoleName, roleName)
        );
    }

    @Override
    public boolean removeRole(List<Long> idList) {
        final List<SysUserRole> userRoleByRidList = sysUserRoleService.getUserRoleByRidList(idList);
        final List<SysRoleMenu> roleMenuByRidList = sysRoleMenuService.getRoleMenuByRidList(idList);
        if (CollectionUtils.isNotEmpty(userRoleByRidList)) {
            sysUserRoleService.removeByIds(
                    userRoleByRidList.stream()
                            .map(SysUserRole::getId)
                            .collect(Collectors.toList())
            );
        }
        if (CollectionUtils.isNotEmpty(roleMenuByRidList)) {
            sysRoleMenuService.removeByIds(
                    roleMenuByRidList.stream()
                            .map(SysRoleMenu::getId)
                            .collect(Collectors.toList())
            );
        }
        return this.removeByIds(idList);
    }
}
